(ns scripts.cljmon.url
  (:use scripts.cljmon.config
        util.utils))

(defn- parse-path [path]
  (let [[url params] (clojure.string/split path #"\?" 2)]
    [url (when params
           (into {}
             (for [item (clojure.string/split params #"[&;]")]
               (let [[k v] (map decode-url (clojure.string/split item #"=" 2))]
                 [(keyword k) v]))))]))

(defn- translate-query-from [{:keys [type name port me? multiple-instances label filter-args]} {:keys [memory-unit disk-unit network-unit log-process-arguments?]}]
  (case type
    :timestamp :timestamp
    :system-info {:type :system-info :unit memory-unit}
    :process-info (merge
                    {:type :process-info :unit memory-unit :log-process-arguments log-process-arguments? :label label :filter-args filter-args}
                    (cond
                      (and name multiple-instances) {:by :name :name name :multiple-instances multiple-instances}
                      name {:by :name :name name}
                      port {:by :port :port port}
                      me? {:by :me}))
    :network-io {:type :network-io :unit network-unit}
    :disk-io {:type :disk-io :unit disk-unit}
    :disk-space {:type :disk-space :unit disk-unit}
    (throw (Exception. (format "'%s' should be system-info, process-info, network-io, disk-io, or disk-space" (clojure.core/name type))))))

(defn- translate-resource-path [path config]
  (let [[path {:keys [name port self multiple-instances label filter-args]}] (parse-path path)
        type (keyword path)
        multiple-instances (case multiple-instances
                             "true" true
                             "1" true
                             "false" false
                             "0" false
                             "acc" :acc nil nil)
        me? (or (= self "true") (= self "1"))]
    (translate-query-from {:type type :name name :port (when port (Integer/parseInt port)) :me? me? :multiple-instances multiple-instances :label label :filter-args filter-args} config)))

(defn translate-resource-url [url config]
  (if-let [[_ host port path] (re-matches #"http://(?:([^:/]+)(?::(\d+))?)/(.+)/?" url)]
    (let [port (if port (Integer/parseInt port) DEFAULT_AGENT_PORT)
          query (translate-resource-path path config)]
      (assoc query :agent {:url (format "http://%s:%d/" host port) :host host :port port}))
    (throw (Exception. (str "Invalid URL " url)))))


